package com.panhu.sparsearray;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;

/**
 * 稀疏数组
 * @author LanChaoHui
 * @version 0.0.1
 * @Type com.panhu.sparsearray.SparseArray.java
 * @date 2021/2/22 15:49
 */
public class SparseArray {

    /**
     * 文件路径
     */
    private static String filePath = "E:/sparseArray.txt";

    public static void main(String[] args) {
        // 创建一个元素的二维数组 11*11
        // 0：表示没有棋子，1表示 黑子，2表示蓝子
        int chessArr1[][] = new int[11][11];
        chessArr1[1][2] = 1;
        chessArr1[2][3] = 2;
        chessArr1[4][5] = 2;
        // 输出原始的二维数组
        System.out.println("原始的二维数组");
        for (int[] row : chessArr1) {
            for (int data : row) {
                System.out.printf("%d\t", data);
            }
            System.out.println();
        }
        // 将二维数组转 稀疏数组的思路
        // 1.先遍历二维数组，得到非0数据的个数
        int sum = 0;
        int col = 0;
        for (int i = 0; i < chessArr1.length; i++) {
            for (int j = 0; j < chessArr1[i].length; j++) {
                if (chessArr1[i][j] != 0) {
                    sum++;
                }
                if (col == 0) {
                    col = chessArr1[i].length;
                }
            }
        }
        System.out.println(sum);
        // 2.来创建一个对应的稀疏数组
        int[][] sparseArray = new int[sum + 1][3];
        sparseArray[0][0] = chessArr1.length;
        sparseArray[0][1] = col;
        sparseArray[0][2] = sum;
        int count = 1;
        for (int i = 0; i < chessArr1.length; i++) {
            for (int j = 0; j < chessArr1[i].length; j++) {
                if (chessArr1[i][j] != 0) {
                    sparseArray[count][0] = i;
                    sparseArray[count][1] = j;
                    sparseArray[count][2] = chessArr1[i][j];
                    count++;
                }
            }
        }
        // 输出稀疏数组
        System.out.println();
        System.out.println("得到的稀疏数组为如下形式");
        for (int[] rows : sparseArray) {
            for (int row : rows) {
                System.out.printf("%d\t", row);
            }
            System.out.println();
        }
        // 从文件中读取
        int[][] sparseArrayTemp = getSparseArray();
        if (sparseArrayTemp[0][0] != -1) {
            // 使用读取出来的稀疏数组
            sparseArray = sparseArrayTemp;
            System.out.println("使用读取出来的稀疏数组");
        }
        // 将稀疏数组恢复成原始的数组
        // 1. 先读取稀疏数组的第一行，根据第一行的数据，创建元素的二维数组，比如 上面的sparseArr [11][11]；
        int chessArr2[][] = new int[sparseArray[0][0]][sparseArray[0][1]];
        // 2. 在读取稀疏数组后几行（第二行）的数据，并赋给元素的二维数组即可；
        for (int i = 1; i < sparseArray.length; i++) {
            chessArr2[sparseArray[i][0]][sparseArray[i][1]] = sparseArray[i][2];
        }
        System.out.println();
        System.out.println("恢复后的二维数组");
        for (int[] row : chessArr2) {
            for (int data : row) {
                System.out.printf("%d\t", data);
            }
            System.out.println();
        }
        if (writeSparseArray(sparseArray)) {
            System.out.println("稀疏数组写入成功");
        } else {
            System.out.println("稀疏数组写入失败");
        }
    }

    /**
     * <p>将稀疏数组写入到磁盘
     * 如下格式
     * 11,11,3:1,2,1:2,3,2:4,5,2
     * </p>
     *
     * @param sparseArray 稀疏数组
     * @return boolean true 写入成功 false 写入失败
     * @date 2021/1/17 16:10
     * @since 0.0.1
     */
    private static boolean writeSparseArray(int[][] sparseArray) {
        try {
            // 判断是否有该文件
            File file = new File(filePath);
            if (!file.getParentFile().exists()) {
                file.mkdirs();
            }
            if (!file.exists()) {
                file.createNewFile();
            }
            FileWriter fileWriter = new FileWriter(filePath);
            // 遍历稀疏数组将其写入文件并通过每个通过,逗号隔开，每行通过*号隔开
            StringBuffer temp = new StringBuffer();
            for (int i = 0; i < sparseArray.length; i++) {
                for (int j = 0; j < sparseArray[i].length; j++) {
                    if (j + 1 != sparseArray[i].length) {
                        temp.append(String.format("%s%s", sparseArray[i][j], ","));
                    } else {
                        temp.append(String.format("%s", sparseArray[i][j]));
                    }
                }
                if (i + 1 != sparseArray.length) {
                    temp.append(":");
                }
            }
            String sparseArrayStr = temp.toString();
            if (!"".equals(sparseArrayStr)) {
                fileWriter.write(sparseArrayStr);
            }
            fileWriter.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * <p>获取磁盘文件中的稀疏数据</p>
     *
     * @return 稀疏数组，如果失败 sparseArray[0][0] = -1 为标记
     * @date 2021/1/17 17:18
     * @since 0.0.1
     */
    private static int[][] getSparseArray() {
        File file = new File(filePath);
        int[][] sparseArray = new int[1][1];
        sparseArray[0][0] = -1;
        if (!file.exists()) {
            return sparseArray;
        }
        // 解析文件
        try {
            BufferedReader bufferedReader = new BufferedReader(new FileReader(file));
            // 就一行
            String sparseArrayStr = bufferedReader.readLine();
            //算出行
            String[] rows = sparseArrayStr.split(":");
            sparseArray = new int[rows.length][3];
            for (int i = 0; i < rows.length; i++) {
                String[] values = rows[i].split(",");
                for (int j = 0; j < values.length; j++) {
                    sparseArray[i][j] = Integer.valueOf(values[j]);
                }
            }
            return sparseArray;
        } catch (Exception e) {
            e.printStackTrace();
            sparseArray[0][0] = -1;
            return sparseArray;
        }
    }
}
